package cn.turboinfo.fuyang.api.domain.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.Map;

@Slf4j
public class ObjectHelper {

    /**
     * 从 MAP 对象按照属性路径读取属性
     *
     * @param obj          对象
     * @param propertyPath 属性路径: a.b.c
     * @return 读取到的值
     */
    public static Object readMapObjectByPropertyPathSilently(Object obj, String propertyPath) {
        String[] paths = StringUtils.split(propertyPath, ".");
        Object result = obj;

        for (String path : paths) {
            if (result == null) {
                break;
            }
            try {
                if (result instanceof Map) {
                    result = ((Map<?, ?>) result).get(path);
                } else {
                    log.error("非 Map 对象不支持读取, propertyPath={}", propertyPath);
                    return null;
                }
            } catch (Exception e) {
                log.error("获取属性出错, propertyPath={}, path={}", propertyPath, path);
                log.error("获取属性出错", e);
                // 出错以后不再继续执行
                return null;
            }
        }

        return result;
    }

    /**
     * 从 MAP 对象按照属性路径读取属性
     *
     * @param obj          对象
     * @param propertyPath 属性路径: a.b.c
     * @param clazz        对象类型
     * @return 读取到的值
     */
    @SuppressWarnings("unchecked")
    public static <T> T readMapObjectByPropertyPathSilently(Object obj, String propertyPath, Class<T> clazz, T defaultValue) {
        Object value = readMapObjectByPropertyPathSilently(obj, propertyPath);
        if (value == null) {
            return defaultValue;
        }
        if (clazz.equals(String.class)) {
            return (T) String.valueOf(value);
        }
        if (clazz.equals(Boolean.class)) {
            return (T) (Boolean) value;
        }
        if (clazz.equals(Long.class)) {
            return (T) Long.valueOf(((Number) value).longValue());
        }
        if (clazz.equals(Integer.class)) {
            return (T) Integer.valueOf(((Number) value).intValue());
        }

        return (T) value;
    }
}
